"""Pylons middleware initialization"""
from beaker.middleware import SessionMiddleware
from paste.cascade import Cascade
from paste.registry import RegistryManager
from paste.urlparser import StaticURLParser
from paste.deploy.converters import asbool
from pylons.middleware import ErrorHandler, StatusCodeRedirect
from pylons.wsgiapp import PylonsApp
from routes.middleware import RoutesMiddleware
from json import dumps, loads
from stylons.config.environment import load_environment
from webob import Request
from hashid import hashId

class JsonMiddleware(object):
    """Simple class converting dict to json for middleware"""

    def __init__(self, wrap_app):
        self.wrap_app = wrap_app

    def __call__(self, environ, start_response):
        obj = self.wrap_app(environ, start_response)
        if isinstance(obj, dict):
            return dumps(obj, separators=(',',':'))
        else:
            return obj

class GetComponentsMiddleware(object):
    """Collect components needed by user and pack it"""
    
    def __init__(self, wrap_app):
        self.wrap_app = wrap_app
        
    def __call__(self, environ, start_response):
        if environ['PATH_INFO'] == '/getComponents/index':
            request = Request(environ)
            post = loads(request.POST['data'])
            obj = {}
            environ['CONTENT_LENGTH'] = 0 # correct POST content length
            if post != [None]:
                for el in post:
                    #TODO new thread for each item
                    env = environ.copy() # make a copy of request
                    env['PATH_INFO'] = el if el[0]=='/' else '/'+el # add slash
                    obj[el] = self.wrap_app(env, start_response) # get request
            return obj
        else:
            obj = self.wrap_app(environ, start_response)
            return obj

def make_app(global_conf, full_stack=True, static_files=True, **app_conf):
    """Create a Pylons WSGI application and return it

    ``global_conf``
        The inherited configuration for this application. Normally from
        the [DEFAULT] section of the Paste ini file.

    ``full_stack``
        Whether this application provides a full WSGI stack (by default,
        meaning it handles its own exceptions and errors). Disable
        full_stack when this application is "managed" by another WSGI
        middleware.

    ``static_files``
        Whether this application serves its own static files; disable
        when another web server is responsible for serving them.

    ``app_conf``
        The application's local configuration. Normally specified in
        the [app:<name>] section of the Paste ini file (where <name>
        defaults to main).

    """
    # Configure the Pylons environment
    config = load_environment(global_conf, app_conf)

    # The Pylons WSGI app
    app = PylonsApp(config=config)

    # Routing/Session Middleware
    app = RoutesMiddleware(app, config['routes.map'], singleton=False)
    app = SessionMiddleware(app, config)

    # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
    app = GetComponentsMiddleware(app)
    app = JsonMiddleware(app)
    if asbool(full_stack):
        # Handle Python exceptions
        app = ErrorHandler(app, global_conf, **config['pylons.errorware'])

        # Display error documents for 401, 403, 404 status codes (and
        # 500 when debug is disabled)
        if asbool(config['debug']):
            app = StatusCodeRedirect(app)
        else:
            app = StatusCodeRedirect(app, [400, 401, 403, 404, 500])

    # Establish the Registry for this application
    app = RegistryManager(app)

    if asbool(static_files):
        # Serve static files
        static_app = StaticURLParser(config['pylons.paths']['static_files'])
        app = Cascade([static_app, app])
    app.config = config
    return app
